package designpattern

import (
	"fmt"

	"github.com/dop251/goja"
)

type Context struct {
	expression Expression
}

func NewContext() *Context {
	return &Context{expression: &JavaScriptExpression{}}
}

func (context *Context) Eval(expr string) float64 {
	return context.expression.interpret(expr)
}

type Expression interface {
	interpret(expr string) float64
}

type JavaScriptExpression struct {
}

func (expression *JavaScriptExpression) interpret(expr string) float64 {
	javascript := fmt.Sprintf("eval(%s).toFixed(6)", expr)
	vm := goja.New()
	v, err := vm.RunString(javascript)
	if err != nil {
		panic("Javascript eval expression exception")
	}

	return v.ToFloat()
}
